package wepay

import (
	"crypto/hmac"
	"crypto/sha256"
	"fmt"
	"io"
	mrand "math/rand"
	"sort"
	"strings"
	"time"

	"github.com/astaxie/beego/logs"
)

type param struct {
	key   string
	value string
}

type paramSlice []param

func newParamList() paramSlice {
	return make([]param, 0)
}

func (p *paramSlice) addParam(key string, value string) {

	if len(value) == 0 {
		return
	}

	var v param

	v.key = key
	v.value = value

	*p = append(*p, v)
}

// 重写 Len() 方法
func (a paramSlice) Len() int {
	return len(a)
}

// 重写 Swap() 方法
func (a paramSlice) Swap(i, j int) {
	a[i], a[j] = a[j], a[i]
}

// 重写 Less() 方法， 从小到大排序
func (a paramSlice) Less(i, j int) bool {
	return a[i].key < a[j].key
}

func getRandomString(lenth int64) string {

	str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	result := ""
	r := mrand.New(mrand.NewSource(time.Now().UnixNano()))
	var i int64
	for i = 0; i < lenth; i++ {
		result += string(str[r.Intn(len(str))])
	}
	return (result)
}

func getHmacCode(s, key string) string {
	h := hmac.New(sha256.New, []byte(key))
	io.WriteString(h, s)
	return fmt.Sprintf("%x", h.Sum(nil))
}

func wechatSign(inputParam []param, orderKey string) string {

	var signStr string

	sort.Sort(paramSlice(inputParam))

	for _, value := range inputParam {
		signStr += value.key + "=" + value.value + "&"
	}

	signStr += "key=" + orderKey

	logs.Debug("param:", signStr)

	hmacStr := getHmacCode(signStr, orderKey)
	//logs.Debug("after hamac:%v", hmacStr)
	return strings.ToUpper(hmacStr)
}
